import copy
from dataclasses import dataclass, field, asdict
from typing import List

from apps.task.parseabs import AncientBooksAbs
from apps.task.place_one_parse import PlaceOneParse


# 日历解析
class ParsePlace(AncientBooksAbs):

    def __init__(self):
        self.inputs = None
        self.one_datas = None
        self._result = None
        self._result_list = []
        self.pop = PlaceOneParse()
        self._finish_deal_len = 0
        self._latest_len = 0

    def set_inputs(self, inputs: str):
        """
        输入的数据可以是多条
        :param inputs:
        :return:
        """
        self.inputs = inputs

    def set_file_info(self, file_list_count):
        """
        多文件的信息，单文件没有这种顾虑
        :param file_list_count:
        :return:
        """
        self.file_list_count = file_list_count
        self.file_count = len(self.file_list_count)

    def get_count_in_file(self, count):
        """"
        获取行在哪个文件的哪一行
        """
        now_count = count
        for line_num, file_name in self.file_list_count:
            if now_count > line_num:
                now_count = now_count - line_num
            elif now_count == line_num:  # 标识这个文件的最后一行
                return now_count - 1, file_name
            else:
                return now_count - 1, file_name
        # 如果第一次 for循环报错，可能是在 data_parse 函数正常执行完后面报的错误
        # 这个时候定位错误 要减去self._latest_len
        now_count = count - self._latest_len
        for line_num, file_name in self.file_list_count:
            if now_count > line_num:
                now_count = now_count - line_num
            elif now_count == line_num:  # 标识这个文件的最后一行
                return now_count - 1, file_name
            else:
                return now_count - 1, file_name
        now_count = count - self._finish_deal_len
        for line_num, file_name in self.file_list_count:
            if now_count > line_num:
                now_count = now_count - line_num
            elif now_count == line_num:  # 标识这个文件的最后一行
                return now_count - 1, file_name
            else:
                return now_count - 1, file_name
        raise Exception("文件量和传入的数据不对")

    def get_list_data(self):
        """
        将每条数据的文本切分到list里面
        :return:
        """
        assert isinstance(self.inputs, str), Exception("输入数据不能为空或不为str的数据")
        return self.inputs.split("\n")

    def get_one_data(self):
        list_data = self.get_list_data()
        for data in list_data:
            if data == "\ufeff":
                continue
            if data.startswith("\ufeff"):
                data = "" + data[len("\ufeff"):]
            yield data

    def data_parse(self, *args, **kwargs):
        """
        解析
        :param args: args[0] == work_id
        :param kwargs:
        :return:
        """
        self._finish_deal_len = 0
        i = 1
        for one_text in self.get_one_data():
            self.pop.now_deal_index_line.append((self._finish_deal_len, one_text))
            if one_text.strip() == "":
                continue
            self.one_datas = one_text
            dicts = self.pop.run_parse(one_text)

            dicts["place_id"] = args[0]+"_"+str(i)
            self._result = dicts
            self._result_list.append(self._result)
            self._latest_len = 1
            self._finish_deal_len = self._finish_deal_len + self._latest_len
            i = i + 1

    def get_parse_result(self, input_dicts, work_info):
        place_datainfo = DataInfo(
            _id=input_dicts["lngid"],
            lngid=input_dicts["lngid"],
            rawid=input_dicts["rawid"],
            latest_date=input_dicts["latest_date"],
            source_type=input_dicts["source_type"],
            type_id=input_dicts["type_id"],
            process_id=input_dicts["process_id"]
        )
        place_info = {
            "work_id": work_info[0],
            "work_name": work_info[1],
            "place_list": copy.deepcopy(self._result_list)
        }
        place_datainfo.place_info = place_info
        return asdict(place_datainfo)


@dataclass
class DataInfo:
    _id: str = ''
    lngid: str = ''
    rawid: str = ''
    latest_date: str = ''
    source_type: int = -1
    type_id: int = -1
    process_id: str = ''
    place_info: List[dict] = field(default_factory=list)
